/**
 * @file bsp_delay.c
 * @brief 延时函数API
 * @author wangh (wanghuan3037@fiberhome.com)
 * @version 1.0
 * @date 2020-05-27
 * @copyright Copyright (c) 2020  烽火通信
 ***************************************************************
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version  <th>Author  <th>Description
 * <tr><td>2020-05-27 <td>1.0      <td>wangh   <td>内容
 * </table>
 */
#include "bsp_delay.h"

#define SYSTEM_USE_FREERTOS


#ifdef SYSTEM_USE_FREERTOS 
#include "FreeRTOS.h"
#include "task.h"

/**
 * @brief ms延时（不阻塞）
 * @param  nms    	毫秒数
 */
void delay_ms(uint32_t nms)
{
    uint32_t  xStart = xTaskGetTickCount();
    
    if( (uint32_t)(xStart + nms) < xStart )	//溢出
    {
        while((xTaskGetTickCount() - xStart) > 0);
        
        while((xTaskGetTickCount() - xStart) < (nms - (0xffffffff - xStart)));
        
    }
    else
        while((xTaskGetTickCount() - xStart) < nms);
}

void delay_ms_isr(uint32_t nms)
{
    uint32_t  xStart = xTaskGetTickCountFromISR();
    
    if( (uint32_t)(xStart + nms) < xStart )	//溢出
    {
        while((xTaskGetTickCountFromISR() - xStart) > 0);
        
        while((xTaskGetTickCountFromISR() - xStart) < (nms - (0xffffffff - xStart)));
        
    }
    else
        while((xTaskGetTickCountFromISR() - xStart) < nms);
}

void hal_delay_cal(uint32_t ms, uint16_t ms_factor)
{
    uint16_t i = 0;
    while(ms--)
    {
        i = ms_factor;
        while(i--);
    }
}

void hal_delay_ms(uint32_t ms)
{
    uint16_t i = 0;
    while(ms--)
    {
        i = 4424;	/* 72MHz:4424, 40MHz:5530 */
        while(i--);
    }
}

#if 1
/**
 * @brief 微妙级延时 \n
 * 72MHz 一个__nop()为13.9 ns， 72个__nop()为1us
 * @param  us          微妙数
 */
void hal_delay_us(uint16_t us)
{
    while(us--)
    {
        __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
        __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
        __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
        __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
        __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
        __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
        __nop();__nop();__nop();
    }
}
#endif

#else
#ifdef STM32F10X
#include "stm32f10x.h"
#elif defined GD32F10X
#include "gd32f10x.h"
#endif

static uint8_t  fac_us = 0;		   
static uint16_t fac_ms = 0;

/**
 * @brief 延时初始化（仅用于非OS）
 */
void delay_init()
{
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);	//选择外部时钟  HCLK/8
    fac_us = SystemCoreClock/8000000;				        //为系统时钟的1/8  
    fac_ms = (uint16_t)fac_us*1000;					        //非OS下,代表每个ms需要的systick时钟数   
}

/**
 * @brief 微妙延时（仅用于非OS）
 * @param  nus      微妙数
 */
void delay_us(uint32_t nus)
{		
    uint32_t temp;	    	 
    SysTick->LOAD = nus*fac_us; 			    //时间加载	  		 
    SysTick->VAL = 0x00;        			    //清空计数器
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk ;	//开始倒数	  
    do
    {
        temp = SysTick->CTRL;
    }while((temp&0x01)&&!(temp&(1<<16)));		//等待时间到达   
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;	//关闭计数器
    SysTick->VAL = 0X00;      					 //清空计数器	 
}

/**
 * @brief ms延时（不阻塞） \n
 * 注意nms的范围,SysTick->LOAD为24位寄存器,所以,最大延时为: nms<=0xffffff*8*1000/SYSCLK
 * SYSCLK单位为Hz,nms单位为ms,对72M条件下,nms<=1864
 * @param  nms    	毫秒数
 */
void delay_ms(uint32_t nms)
{	 		  	  
    uint32_t temp;		   
    SysTick->LOAD = (uint32_t)nms*fac_ms;	    //时间加载(SysTick->LOAD为24bit)
    SysTick->VAL = 0x00;					    //清空计数器
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk ;	//开始倒数  
    do
    {
        temp = SysTick->CTRL;
    }while((temp&0x01)&&!(temp&(1<<16)));		//等待时间到达   
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;	//关闭计数器
    SysTick->VAL = 0X00;       					//清空计数器	  	    
}

/**
 * @brief 秒延时
 * @param  s        秒数
 */
void delay(uint16_t s)
{
    while(s--)
        delay_ms(1000);
}

#endif




/*********** (C) COPYRIGHT 2020 FiberHome *****END OF FILE****/
